<template>
  <div class="chat-message-item" :class="[`is-message-${from}`, `is-side-${side}`]">
    <div class="main">
      <div class="name" v-if="isServiceSideMessage">{{ name }}</div>
      <div class="wrapper">
        <div class="avatar"></div>
        <div class="bar">
          <div class="content" v-html="formatContent" />
          <span class="time">{{ formatTime }}</span>
        </div>
        <div class="status" :class="{ 'is-read': read }" v-if="isServiceSideMessage">未读</div>
      </div>
      <div class="operation" v-if="isServiceSideMessage">
        <span class="cursor-pointer text-xs text-gray-500" @click="emit('withdraw')">撤回</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import dayjs from 'dayjs'
import { faceList, UserTypeEnum } from '@/common/constants'
import type { IChatMessageItem } from '@/common/types'

const emit = defineEmits<{
  withdraw: [item: IChatMessageItem]
}>()

interface Props extends IChatMessageItem {
  side: UserTypeEnum
}

const props = defineProps<Props>()

const isVisitorMessage = computed(() => props.role === UserTypeEnum.VISITOR)
const isServiceMessage = computed(() => props.role === UserTypeEnum.SERVICE)
const isVisitorSide = computed(() => props.side === UserTypeEnum.VISITOR)
const isServiceSide = computed(() => props.side === UserTypeEnum.SERVICE)
const isServiceSideMessage = computed(() => isServiceSide.value && isServiceMessage.value)

const formatTime = computed(() => dayjs(props.time).format('YYYY-MM-DD HH:mm:ss'))

const formatContent = computed(() => {
  return props.content?.replace(/face\[([^\s\[\]]+?)]/g, (substring, $1) => {
    const face = faceList.find((faceItem) => faceItem.key === $1)
    if (!face?.img) return ''
    return `<img class="face" src="${face.img}" alt=""/>`
  })
})
</script>

<style lang="less" scoped>
.message-right-layout {
  .wrapper {
    flex-direction: row-reverse;
  }
}

.message-left-bar(@color) {
  .bar {
    background: @color;
    &::before {
      left: -0.375rem;
      border-right: 0.625rem solid @color;
    }
  }

  .avatar {
    margin-right: 1rem;
  }
}

.message-right-bar(@color) {
  .bar {
    background: @color;
    &::before {
      border-right: 0.625rem solid @color;
      right: -0.375rem;
      transform: rotate(180deg);
    }
  }

  .avatar {
    margin-left: 1rem;
  }
}

.chat-message-item {
  padding: 0 1rem;
  margin-top: 1rem;

  &:last-child {
    margin-bottom: 1rem;
  }

  .wrapper {
    overflow: hidden;
    display: flex;
  }

  .avatar {
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border-radius: 50%;
    background: #dcdcdc;
  }

  .name {
    color: #666;
    margin-bottom: 0.5rem;
    text-align: right;
    font-size: 0.875rem;
  }

  .status {
    padding: 0.625rem 0.75rem;
    font-size: 0.75rem;
    color: #ff5722;
    line-height: 1.25rem;
    &.is-read {
      color: #999;
    }
  }

  .bar {
    padding: 0.5rem 0.75rem;
    border-radius: 0.375rem;
    max-width: 20rem;
    position: relative;
    box-sizing: border-box;

    &::before {
      position: absolute;
      content: '';
      top: 0.5rem;
      border-top: 0.625rem solid transparent;
      border-bottom: 0.625rem solid transparent;
    }

    .time {
      color: #666;
      font-size: 0.75rem;
      float: right;
      line-height: 1;
      margin-top: 0.375rem;
    }
  }

  .content {
    line-height: 1.25rem;
    font-size: 0.875rem;
    text-align: justify;
    :deep(.face) {
      width: 1.25rem;
      height: 1.25rem;
      vertical-align: text-bottom;
    }
  }

  &.is-side-service {
    &.is-message-visitor {
      .message-left-bar(#c0dcf4);
    }

    &.is-message-service {
      .message-right-layout();
      .message-right-bar(#fff);

      .operation {
        margin-top: 0.375rem;
        text-align: right;
        padding-right: 3.25rem;
      }
    }
  }

  &.is-side-visitor {
    &.is-message-service {
      .message-left-bar(#fff);
    }

    &.is-message-visitor {
      .message-right-layout();
      .message-right-bar(#c0dcf4);
    }
  }
}
</style>
